home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / metkit / kbound.cpp < prev    next >
C/C++ Source or Header  |  1997-06-07  |  5KB  |  163 lines

  1. //    Copyright (C) 1996, 1997 Meta Four Software.  All rights reserved.
  2. //
  3. //  See the comments in "kbound.h" for details on how to use this code.
  4. //
  5. //! rev="$Id: kbound.cpp,v 1.2 1997/05/27 00:06:43 jcw Rel $"
  6.  
  7. #include "kbound.h"
  8.  
  9. /////////////////////////////////////////////////////////////////////////////
  10.  
  11.         // the default encoder does nothing
  12.  
  13.     static void NullEncoder(bool encode_, int block_, char* ptr_, int len_)
  14.     {
  15.     }
  16.  
  17.     void (*c4_BoundStorage::_Encoder)(bool,int,char*,int) = NullEncoder;
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20.  
  21. #define FLAG_BYTES    2     /* Number of bytes used by copy flag. */
  22. #define FLAG_COMPRESS 0     /* Signals that compression occurred. */
  23. #define FLAG_COPY     1     /* Signals that a copyover occurred.  */
  24. static void fast_copy(BYTE *p_src,BYTE *p_dst,int len) /* Fast copy routine. */
  25. {while (len--) *p_dst++=*p_src++;}
  26.  
  27. void lzrw1_decompress(BYTE *p_src_first,DWORD src_len,
  28.                       BYTE *p_dst_first,DWORD *p_dst_len)
  29. /* Input  : Specify input block using p_src_first and src_len.          */
  30. /* Input  : Point p_dst_first to the start of the output zone.          */
  31. /* Input  : Point p_dst_len to a DWORD to receive the output length.    */
  32. /* Input  : Input block and output zone must not overlap. User knows    */
  33. /* Input  : upperbound on output block length from earlier compression. */
  34. /* Input  : In any case, maximum expansion possible is eight times.     */
  35. /* Output : Length of output block written to *p_dst_len.               */
  36. /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
  37. /* Output : Writes only  in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
  38. {WORD controlbits=0, control;
  39.  BYTE *p_src=p_src_first+FLAG_BYTES, *p_dst=p_dst_first,
  40.        *p_src_post=p_src_first+src_len;
  41.  if (*p_src_first==FLAG_COPY)
  42.    {fast_copy(p_src_first+FLAG_BYTES,p_dst_first,(int)src_len-FLAG_BYTES);
  43.     *p_dst_len=src_len-FLAG_BYTES; return;}
  44.  while (p_src!=p_src_post)
  45.    {if (controlbits==0)
  46.       {control=*p_src++; control|=(*p_src++)<<8; controlbits=16;}
  47.     if (control&1)
  48.       {WORD offset,len; BYTE *p;
  49.        offset=(*p_src&0xF0)<<4; len=1+(*p_src++&0xF);
  50.        offset+=*p_src++&0xFF; p=p_dst-offset;
  51.        while (len--) *p_dst++=*p++;}
  52.     else
  53.        *p_dst++=*p_src++;
  54.     control>>=1; controlbits--;
  55.    }
  56.  *p_dst_len=p_dst-p_dst_first;
  57. }
  58.  
  59. /////////////////////////////////////////////////////////////////////////////
  60.  
  61. class c4_BoundReader : public CFile
  62. {
  63.     BYTE *_begin, *_curr, *_end;
  64.     int _base;
  65.     
  66. public:
  67.     c4_BoundReader (int base_)
  68.         : _base (base_)
  69.     {          
  70.         _begin = _curr = _end = new BYTE [c4_BoundStorage::kBlockSize];
  71.     }
  72.     
  73.     virtual ~c4_BoundReader ()
  74.     {   
  75.         delete [] _begin;
  76.     }
  77.     
  78.     virtual UINT Read(void* lpBuf, UINT nCount)
  79.     {
  80.         UINT n = nCount;
  81.         
  82.         while (n > 0)
  83.         {
  84.             if (_curr >= _end && !LoadNextBlock())
  85.                 break;
  86.             
  87.             int i = n;
  88.             if (i > _end - _curr)
  89.                 i = _end - _curr;
  90.             
  91.             memcpy(lpBuf, _curr, i);
  92.             lpBuf = (BYTE*) lpBuf + i;
  93.             
  94.             _curr += i;
  95.             n -= i;
  96.         }  
  97.         
  98.         return nCount - n;
  99.     }
  100.     
  101.     virtual void Write(const void* lpBuf, UINT nCount)
  102.     {
  103.         ASSERT(0);
  104.     }
  105.  
  106. private:
  107.     bool LoadNextBlock()
  108.     {                               
  109. #ifdef _WIN32
  110.         HINSTANCE hInst = 0;
  111. #else
  112.         HINSTANCE hInst = AfxGetResourceHandle();
  113. #endif
  114.         
  115.         HRSRC hRes = ::FindResource(hInst, MAKEINTRESOURCE(_base++), RT_RCDATA);
  116.         if (hRes)
  117.         {
  118.             HGLOBAL hData = ::LoadResource(hInst, hRes);
  119.             if (hData)
  120.             {
  121.                 const BYTE* p = (const BYTE*) ::LockResource(hData);
  122.                 DWORD k = *(const WORD*) p >> 1;
  123.                 ASSERT(k <= c4_BoundStorage::kBlockSize + 2);
  124.  
  125.                 c4_Bytes temp;
  126.                 BYTE* tempBuf = (BYTE*) memcpy(temp.SetBuffer((int) k), p, (WORD)k);
  127.                 *(WORD*) tempBuf &= 1;        // restore the copy flag
  128.  
  129.                 ::UnlockResource(hData);
  130.                 ::FreeResource(hData);
  131.  
  132.                 ASSERT(c4_BoundStorage::_Encoder);
  133.                 c4_BoundStorage::_Encoder(false, _base - 1, 
  134.                                                 (char*) tempBuf + 2, (int) k - 2);
  135.  
  136.                 lzrw1_decompress(tempBuf, k, _begin, &k);
  137.                 ASSERT(k <= c4_BoundStorage::kBlockSize);
  138.  
  139.                 _curr = _begin;
  140.                 _end = _begin + k;
  141.  
  142.                 return true;
  143.             }
  144.         }    
  145.         
  146.         return false;
  147.     }
  148. };
  149.  
  150. /////////////////////////////////////////////////////////////////////////////
  151.  
  152. c4_BoundStorage::c4_BoundStorage (int base_)
  153. {
  154.     c4_BoundReader reader (base_);
  155.     LoadFromStream(&reader);
  156. }
  157.  
  158. c4_BoundStorage::~c4_BoundStorage ()
  159. {
  160. }
  161.  
  162. /////////////////////////////////////////////////////////////////////////////
  163.